package ao.com.bna.controle;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

import org.primefaces.model.DualListModel;

import ao.com.bna.beans.ItemSuplemento;
import ao.com.bna.beans.Nota;
import ao.com.bna.beans.Suplemento;
import ao.com.bna.dao.NotaDao;
import ao.com.bna.dao.SuplementoDao;
import ao.com.bna.util.BeanFactory;
import ao.com.bna.util.JsfUtil;

@ManagedBean
@SessionScoped
public class SuplementoControle {
	private Suplemento infoBean = new Suplemento();
	private List<Suplemento> listaSuplementos = new ArrayList<Suplemento>();
	private List<Nota> listaSource = new ArrayList<Nota>();
	private List<Nota> listaTarget = new ArrayList<Nota>();
	private DualListModel<Nota> listaNotas = new DualListModel<Nota>(listaSource, listaTarget);
	private SuplementoDao dao;
	private String estadoCorrente;
	private String paginaDestino;
	private String tituloPagina;

	public SuplementoControle() {
		actualizaTela();
	}

	/**
	 * @return the infoBean
	 */
	public Suplemento getInfoBean() {
		return infoBean;
	}

	/**
	 * @param infoBean
	 *            the infoBean to set
	 */
	public void setInfoBean(Suplemento infoBean) {
		this.infoBean = infoBean;
	}

	/**
	 * @return the listaInfos
	 */
	public ListDataModel<Suplemento> getListaInfos() {
		return new ListDataModel<Suplemento>(listaSuplementos);
	}

	/**
	 * @return the listaNotas
	 */
	public DualListModel<Nota> getListaNotas() {
		return listaNotas;
	}

	/**
	 * @param listaNotas
	 *            the listaNotas to set
	 */
	public void setListaNotas(
			DualListModel<Nota> listaNotas) {
		this.listaNotas = listaNotas;
	}
	
	
	

	/**
	 * @return the listaSuplementos
	 */
	public List<Suplemento> getListaSuplementos() {
		return listaSuplementos;
	}

	/**
	 * @param listaSuplementos the listaSuplementos to set
	 */
	public void setListaSuplementos(List<Suplemento> listaSuplementos) {
		this.listaSuplementos = listaSuplementos;
	}

	/**
	 * @return the listaSource
	 */
	public List<Nota> getListaSource() {
		return listaSource;
	}

	/**
	 * @param listaSource the listaSource to set
	 */
	public void setListaSource(List<Nota> listaSource) {
		this.listaSource = listaSource;
	}

	/**
	 * @return the listaTarget
	 */
	public List<Nota> getListaTarget() {
		return listaTarget;
	}

	/**
	 * @param listaTarget the listaTarget to set
	 */
	public void setListaTarget(List<Nota> listaTarget) {
		this.listaTarget = listaTarget;
	}

	/**
	 * @return the dao
	 */
	public SuplementoDao getDao() {
		return dao;
	}

	/**
	 * @param suplementoDao
	 *            the suplementoDao to set
	 */
	public void setDao(SuplementoDao dao) {
		this.dao = dao;
	}

	private void actualizaTela() {
		infoBean = new Suplemento();
		dao = (SuplementoDao) BeanFactory.getBean("suplementoDao", SuplementoDao.class);
		listaSuplementos = dao.listar();
		
		List<ItemSuplemento> listaItemReq = infoBean.getItemSuplementos();
		for (ItemSuplemento itemSuplemento : listaItemReq) {
			listaTarget.add(itemSuplemento.getNota());
		}
		
		NotaDao pdao = (NotaDao) BeanFactory.getBean("notaDao", NotaDao.class);
		listaSource = pdao.listar();
		//listaNotas = new DualListModel<Nota>(listaSource, listaTarget);
		
		tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("suplementoTituloListar");
	}

	/**
	 * @see Metodo que ivoca o metodo gravar apartir da classe EstadoDao
	 */
	public String gravar() {
		try {
			Date dt = new Date();
			infoBean.setDataAlteracao((Date)dt.clone());
			listaTarget = getListaNotas().getTarget();
			
			if (this.isEstadoAdicionar() && listaTarget.size() > 0) {
				infoBean.setDataRegisto((Date)dt.clone());
				this.dao.gravar(getInfoBean(), listaTarget);
				//this.dao.gravar(getInfoBean());
				
				JsfUtil.addSuccessMessage(ResourceBundle.getBundle(
						"resources.mensagens").getString("geralRegistoCriado"));
				actualizaTela();
				return this.preparaAdicionar();
			} else if (this.isEstadoActualizar() && listaTarget.size() > 0) {
				this.dao.gravar(getInfoBean(), listaTarget);
				JsfUtil.addSuccessMessage(ResourceBundle.getBundle(
						"resources.mensagens")
						.getString("geralRegistoAlterado"));
				// /actualizaTela();
				this.setEstadoCorrente(JsfUtil.ESTADO_FORMVAZIO);
				return null; // this.voltar();
			} else {
				JsfUtil.addInfoMessage("A lista de notas está vazia");
				return null; // this.voltar();
			}
			//return null;
		} catch (Exception e) {
			JsfUtil.addErrorMessage(
					e,
					ResourceBundle.getBundle("resources.mensagens").getString(
							"geralErroDePersistencia"));
			return null;
		}
	}

	/**
	 * @see Metodo que obtem um registo
	 */
	public Suplemento obterPorID() {
		tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("suplementoTituloListar");
		return dao.obterPorID(getInfoBean().getId());
	}

	/**
	 * @see Metodo que ivoca o metodo remover apartir da classe EstadoDao
	 */
	public String excluir() {
		try {
			dao.remover(this.getInfoBean());
			JsfUtil.addSuccessMessage(ResourceBundle.getBundle(
					"resources.mensagens").getString("geralRegistoEliminado"));
			setEstadoCorrente(JsfUtil.ESTADO_FORMVAZIO);
			return null; // this.voltar();
		} catch (Exception e) {
			JsfUtil.addErrorMessage(
					e,
					ResourceBundle.getBundle("resources.mensagens").getString(
							"geralErroDePersistencia"));
			return null;
		}
	}

	public SelectItem[] getItemsAvailableSelectOneEmpety() {
		List<Suplemento> lista = new ArrayList<Suplemento>();
		return JsfUtil.getSelectItems(lista, true);
	}

	public SelectItem[] getItemsAvailableSelectMany() {
		return JsfUtil.getSelectItems(this.dao.listar(), false);
	}

	public SelectItem[] getItemsAvailableSelectOne() {
		return JsfUtil.getSelectItems(this.dao.listar(), true);
	}

	@FacesConverter(forClass = Suplemento.class)
	public static class EntityConverter implements Converter {

		public Object getAsObject(FacesContext facesContext,
				UIComponent component, String value) {
			if (value == null || value.length() == 0) {
				return null;
			}
			SuplementoControle controller = (SuplementoControle) facesContext
					.getApplication()
					.getELResolver()
					.getValue(facesContext.getELContext(), null,
							"suplementoControle");
			return controller.dao.obterPorID(getKey(value));
		}

		java.lang.Long getKey(String value) {
			java.lang.Long key;
			key = Long.valueOf(value);
			return key;
		}

		String getStringKey(java.lang.Long value) {
			StringBuffer sb = new StringBuffer();
			sb.append(value);
			return sb.toString();
		}

		public String getAsString(FacesContext facesContext,
				UIComponent component, Object object) {
			if (object == null) {
				return null;
			}
			if (object instanceof Suplemento) {
				Suplemento o = (Suplemento) object;
				return getStringKey(o.getId());
			} else {
				throw new IllegalArgumentException("object " + object
						+ " is of type " + object.getClass().getName()
						+ "; expected type: " + Suplemento.class.getName());
			}
		}

	}

	/*
	 * MÈtodos que expıem o estado da pagina
	 */

	/**
	 * Prepara view detalhe
	 */
	public String preparaDetalhes() {
		setEstadoCorrente(JsfUtil.ESTADO_DETALHES);
		tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("suplementoTituloDetalhes");
		return null;
	}

	public String novo() {
		NotaDao pdao = (NotaDao) BeanFactory.getBean("notaDao", NotaDao.class);
		infoBean = new Suplemento();
		listaTarget = new ArrayList<Nota>(); 
		listaSource = pdao.listar();
		listaNotas = new DualListModel<Nota>(listaSource, listaTarget);
		
		return ResourceBundle.getBundle("resources.mensagens").getString(
				"suplementoPaginaCRUD");
	}

	/**
	 * Prepara view adicionar
	 */
	public String preparaAdicionar() {
		setEstadoCorrente(JsfUtil.ESTADO_ADICIONAR);
		tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("suplementoTituloRegistar");
		return novo();
	}

	/**
	 * Prepara view editar
	 */
	public String preparaEditar() {
		NotaDao pdao = (NotaDao) BeanFactory.getBean("notaDao", NotaDao.class);
		listaSource = pdao.listar();
		//------------------------------------------------------------------
		List<ItemSuplemento> listaItemReq = dao.listarItems();
		for (ItemSuplemento itemSuplemento : listaItemReq) {
			Suplemento req = itemSuplemento.getSuplemento();
			if (req.equals(infoBean)) {
				listaTarget.add(itemSuplemento.getNota());
			}
		}
		listaNotas = new DualListModel<Nota>(listaSource, listaTarget);
		
		//------------------------------------------------------------------
		setEstadoCorrente(JsfUtil.ESTADO_ACTUALIZAR);
		tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("suplementoTituloAlterar");
		return ResourceBundle.getBundle("resources.mensagens").getString(
				"suplementoPaginaCRUD");
	}

	/**
	 * Prepara view eliminar
	 */
	public String preparaEliminar() {
		setEstadoCorrente(JsfUtil.ESTADO_ELIMINAR);
		tituloPagina = ResourceBundle.getBundle("resources.mensagens")
				.getString("suplementoTituloEliminar");
		//------------------------------------------------------------------
		NotaDao pdao = new NotaDao();
		listaSource = pdao.listar();
		listaTarget = new ArrayList<Nota>();
		
		List<ItemSuplemento> itemsReq = dao.listarItems();
		for (ItemSuplemento itemSuplemento : itemsReq) {
			if (itemSuplemento.getSuplemento().equals(infoBean)) {
				listaTarget.add(itemSuplemento.getNota());
			}
		}
		//------------------------------------------------------------------
		return ResourceBundle.getBundle("resources.mensagens").getString(
				"suplementoPaginaCRUD");
	}

	/**
	 * Referente ao botao voltar
	 */
	public String voltar() {
		actualizaTela();
		return ResourceBundle.getBundle("resources.mensagens").getString(
				"suplementoPaginaListar");
	}

	// //////////////////////////////////
	public boolean isEstadoPesquisar() {
		String state = this.getEstadoCorrente();
		return (state == null || JsfUtil.ESTADO_PESQUISAR.equals(state));
	}

	public boolean isEstadoAdicionar() {
		return JsfUtil.ESTADO_ADICIONAR.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoActualizar() {
		return JsfUtil.ESTADO_ACTUALIZAR.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoEliminar() {
		return JsfUtil.ESTADO_ELIMINAR.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoDetalhe() {
		return JsfUtil.ESTADO_DETALHES.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoFormVazio() {
		return JsfUtil.ESTADO_FORMVAZIO.equals(this.getEstadoCorrente());
	}

	public boolean isEstadoCrud() {
		return (this.isEstadoAdicionar() || this.isEstadoActualizar()
				|| this.isEstadoEliminar() || this.isEstadoDetalhe() || this
				.isEstadoFormVazio());
	}

	/**
	 * @return the estadoCorrente
	 */
	public String getEstadoCorrente() {
		return estadoCorrente;
	}

	/**
	 * @param estadoCorrente
	 *            the estadoCorrente to set
	 */
	public void setEstadoCorrente(String estadoCorrente) {
		this.estadoCorrente = estadoCorrente;
	}

	/**
	 * @return the paginaDestino
	 */
	public String getPaginaDestino() {
		return paginaDestino;
	}

	/**
	 * @param paginaDestino
	 *            the paginaDestino to set
	 */
	public void setPaginaDestino(String paginaDestino) {
		this.paginaDestino = paginaDestino;
	}

	/**
	 * @return the tituloPagina
	 */
	public String getTituloPagina() {
		return tituloPagina;
	}

	/**
	 * @param tituloPagina
	 *            the tituloPagina to set
	 */
	public void setTituloPagina(String tituloPagina) {
		this.tituloPagina = tituloPagina;
	}

}
